//package mn.idax.exchange.otc.task;
//
//import com.alibaba.fastjson.JSON;
//import com.fasterxml.jackson.core.type.TypeReference;
//import com.google.common.collect.Lists;
//import com.google.common.collect.Maps;
//import mn.idax.exchange.common.CalendarUtil;
//import mn.idax.exchange.otc.constant.CommonConstant;
//import mn.idax.exchange.otc.constant.ReferenceExchageConstant;
//import mn.idax.exchange.otc.entity.ExchageMarketPrice;
//import mn.idax.exchange.otc.service.ClearCacheService;
//import mn.idax.exchange.otc.service.impl.MemoryService;
//import mn.idax.exchange.otc.util.HttpClientUtil;
//import mn.idax.exchange.otc.util.JsonUtil;
//import mn.idax.exchange.otc.util.LogUtils;
//import mn.idax.exchange.otc.util.OkHttpClientUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.commons.lang3.exception.ExceptionUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.scheduling.annotation.EnableScheduling;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//import org.springframework.util.CollectionUtils;
//
//import java.io.IOException;
//import java.math.BigDecimal;
//import java.text.MessageFormat;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//import java.util.Optional;
//
//
///**
// * @Auther: .jension
// * @Time 2018.11.08 16:11
// * @Description:参考交易所行情数据定时任务 coinmarketcap API
// * <p>
// * https://api.coinmarketcap.com/v1/ticker/tether/?convert=USD
// * https://api.coinmarketcap.com/v1/ticker/Bitcoin/?convert=USD
// * https://api.coinmarketcap.com/v1/ticker/Ethereum/?convert=USD
// * bitstamp API
// * https://www.bitstamp.net/api/v2/ticker/BTCUSD/
// * https://www.bitstamp.net/api/v2/ticker/ETHUSD/
// * bitfinex API
// * https://api.bitfinex.com/v1/pubticker/ETHUSD
// * https://api.bitfinex.com/v1/pubticker/BTCUSD
// *
// * 新增BITCNY 2019-10-22 没有bitcny_usdt交易对  转了一次
// * api地址:https://www.zb.com/api#rkxgwlsqnlpypod
// * http://api.zb.plus/data/v1/ticker?market=bitcny_qc
// * http://api.zb.plus/data/v1/ticker?market=usdt_qc
// */
//@Component
//@EnableScheduling
//public class ReferenceExchagePriceJob extends ReferenceExchageConstant {
//
//    @Autowired
//    private StringRedisTemplate redisTemplate;
//
//    @Autowired
//    private ClearCacheService clearCacheService;
//
//    /**
//     * 格式key : ReferenceExchage:BTCCNY:coinmarketcap
//     */
//    private Map<String, ExchageMarketPrice> exchagePriceMap = Maps.newHashMap();
//
//    private Map<String, List<ExchageMarketPrice>> pairsPriceMap = Maps.newHashMap();
//
//    @Scheduled(cron = "0 0/1 * * * ?")
//    public void execute() {
//        // 防止加载会在ExchangeRateJob之前执行
//        if (null == ExchangeRateJob.rateMap) {
//            LogUtils.info(ReferenceExchagePriceJob.class, "ExchangeRateJob.rateMap Is Null Return");
//            return;
//        }
//        // 清空pairsPriceMap
//        pairsPriceMap.clear();
//        // 获取参考交易所的行情价格
//        getExchangePrice();
//        // 计算每个交易对的平均值 并覆盖redis中的值
//        calculationAverage();
//
//        LogUtils.info(ReferenceExchagePriceJob.class, "ReferenceExchagePriceJobPairsPriceMap execute run end. ");
//    }
//
//    public void calculationBitcnyPirce(){
//        Map<String, Object> bitcny_qc = OkHttpClientUtils.get(ZI_BITCNY_QC_API, null, new TypeReference<Map<String, Object>>() {});
//
//        Map<String, Object> usdt_qc = OkHttpClientUtils.get(ZI_USDT_QC_API, null, new TypeReference<Map<String, Object>>() {});
//
//        if ((null == bitcny_qc || bitcny_qc.containsKey("error")) || ((null == usdt_qc || usdt_qc.containsKey("error")))) {
//            LogUtils.error(this.getClass(), "getZBTickerFail " + JSON.toJSONString(bitcny_qc) + ", " + JSON.toJSONString(usdt_qc));
//        } else {
//            BigDecimal bitcny_qc_last = new BigDecimal(((Map) bitcny_qc.get("ticker")).get("last").toString());
//            BigDecimal usdt_qc_last = new BigDecimal(((Map) usdt_qc.get("ticker")).get("last").toString());
//
//            try {
//                calculationCurrencyPriceAlsoStorage(BITCNY, BITCNY_EXCHANGE,
//                        bitcny_qc_last.divide(usdt_qc_last, 2, BigDecimal.ROUND_DOWN).toPlainString());
//            } catch (IOException e) {
//                LogUtils.warn(this.getClass(), "calculationBitcnyPirceError " +  ExceptionUtils.getStackTrace(e));
//            }
//
//        }
//    }
//
//    /**
//     * 获取参考交易所的行情价格
//     */
//    public void getExchangePrice() {
//
//        // 查询所有交易所中所有交易对的价格
//        for (int i = 0; i < marketPairs.length; i++) {
//            if (marketPairs[i].equals(BITCNY)) {
//                try {
//                    Object bitcnyLastPrice = MemoryService.SYSTEMSETTINGMAP.get(CommonConstant.OTC_BITCNY_LASTPRICE);
//                    calculationCurrencyPriceAlsoStorage(BITCNY, BITCNY_EXCHANGE, Objects.isNull(bitcnyLastPrice) ? "0" : (String) bitcnyLastPrice);
//                } catch (IOException e) {
//                    LogUtils.warn(this.getClass(), "calculationBitcnyPirceError " +  ExceptionUtils.getStackTrace(e));
//                }
//                continue;
//            } else if (marketPairs[i].equals(CZZ)){
//                try {
//                    Object czzLastPrice = MemoryService.SYSTEMSETTINGMAP.get(CommonConstant.OTC_CZZ_LASTPRICE);
//                    calculationCurrencyPriceAlsoStorage(CZZ, CZZ_EXCHANGE, Objects.isNull(czzLastPrice) ? "0" : (String) czzLastPrice);
//                } catch (IOException e) {
//                    LogUtils.warn(this.getClass(), "calculationCzzPirceError " +  ExceptionUtils.getStackTrace(e));
//                }
//                continue;
//            }
//            for (int j = 0; j < exchangeName.length; j++) {
//                // 特判只有coinmarketcap交易所,有USDT_USD交易对
//                if (marketPairs[i].equals(marketPairs[2]) && !exchangeName[j].equals(exchangeName[0])) {
//                    continue;
//                }
//                // 请求交易所API
//                Map<String, String> respResult = requestExchangeApi(marketPairs[i], exchangeName[j]);
//
//                LogUtils.warn(ReferenceExchagePriceJob.class, "getExchangePrice.." + JSON.toJSONString(respResult));
//                // Is Success
//                if (Objects.nonNull(respResult) && StringUtils.equals(respResult.get("code"),respResultSuccessCode) && !StringUtils.isEmpty(respResult.get("last"))) {
//                    // 计算其他币种价格，并加入缓存
//                    try {
//                        calculationCurrencyPriceAlsoStorage(marketPairs[i], exchangeName[j], respResult.get("last"));
//                    } catch (Exception e) {
//                        LogUtils.warn(ReferenceExchagePriceJob.class, "getExchangePriceParse fail.." + ExceptionUtils.getStackTrace(e));
//                    }
//                } else {
//                    //調用第三方api未返回數據
//                    LogUtils.warn(ReferenceExchagePriceJob.class, "getExchangePriceNoData block.cc ticker with no data. MARKET_PAIRS[" + marketPairs[i] + "],EXCHANGE_NAME[" + exchangeName[j] + "]");
//
//                }
//            }
//        }
//
//    }
//
//    /**
//     * 请求交易所API
//     *
//     * @param marketPairs
//     * @param exchangeName
//     * @return
//     */
//    public Map<String, String> requestExchangeApi(String marketPairs, String exchangeName) {
//        // 获取APIURL
//        MessageFormat messageFormat = exchangeApiUrl.get(exchangeName);
//        // 替换参数请求接口
//        String[] param = new String[]{marketPairs, currencyUSD};
//        if (exchangeName.equals(COINMARKETCAP)){
//            param = new String[]{coinmarketcapTetherName.get(marketPairs), currencyUSD};
//        } else if (exchangeName.equals(BITSTAMP)){
//            param = new String[]{marketPairs.toLowerCase(), currencyUSD.toLowerCase()};
//        }
////        String param0 = exchangeName.equals(COINMARKETCAP) ? coinmarketcapTetherName.get(marketPairs) : marketPairs;
////        String[] param = new String[]{param0, currencyUSD};
//        LogUtils.info(this.getClass(),"requestExchangeApi,{}",messageFormat.format(param));
//        return responseExchangeApi(HttpClientUtil.httpsRequest(messageFormat.format(param), "GET", null), exchangeName);
//    }
//
//    /**
//     * 响应交易所API
//     *
//     * @param respString
//     * @param exchangeName
//     */
//    public Map<String, String> responseExchangeApi(String respString, String exchangeName) {
//        Map<String, String> responseMap = Maps.newHashMap();
//        try {
//            // respString清除字符串中的[]，为了统一转译Map
//            respString = respString.replace("[", "").replace("]", "");
//
//            Map<String, Object> stringObjectMap = JsonUtil.readValue(respString, new TypeReference<Map<String, Object>>() {
//            });
//            // Is Error coinmarketcap{error}, bitfinex{message}
//            if (null == stringObjectMap || null != stringObjectMap.get("error") || null != stringObjectMap.get("message")) {
//                responseMap.put("code", "responseObject_error");
//                LogUtils.info(ReferenceExchagePriceJob.class, "responseExchangeApi responseObject error. respString[" + respString + "],exchangeName[" + exchangeName + "]");
//                return responseMap;
//            }
//            switch (exchangeName) {
//                case COINMARKETCAP:
//                    responseMap.put("last", String.valueOf(stringObjectMap.get("price_usd")));
//                    break;
//                case BITSTAMP:
//                    responseMap.put("last", String.valueOf(stringObjectMap.get("last")));
//                    break;
//                case BITFINEX:
//                    responseMap.put("last", String.valueOf(stringObjectMap.get("last_price")));
//                    break;
//                default:
//                    break;
//            }
//            responseMap.put("code", respResultSuccessCode);
//
//        } catch (IOException e) {
//            //調用第三方api未返回數據
//            LogUtils.info(ReferenceExchagePriceJob.class, "responseExchangeApi Transformation occur mistakes,because of remote return no data. respString[" + respString + "],exchangeName[" + exchangeName + "]");
//        }
//        return responseMap;
//    }
//
//    /**
//     * 根据美元计算其他币种价格，并加入缓存
//     *
//     * @param symbolPair
//     * @param exchangeName
//     * @param last
//     */
//    public void calculationCurrencyPriceAlsoStorage(String symbolPair, String exchangeName, String last) throws IOException {
//        // 遍历所有币种
//        for (String currency : allCurrency) {
//            // 获取交易对前缀 + 当前币种
//            String pairsName = symbolPair.split(DELIMITER)[0] + currency;
//            // in pairsPriceMap
//            inPairsPriceMapReferenceExchage(redisExchangeFileName + ":" + pairsName, exchangeName, ExchangeRateJob.rateTransformation(new BigDecimal(last), currency));
//        }
//    }
//
//    /**
//     * 计算交易对平均值
//     */
//    public void calculationAverage() {
//        try {
//            for (String key : pairsPriceMap.keySet()) {
//                List<ExchageMarketPrice> exchageMarketPrices = pairsPriceMap.get(key);
//                // 只有一个交易所就不用算平均值了
//                if (exchageMarketPrices.size() < 2) {
//                    redisTemplate.opsForValue().set(key, JsonUtil.writeValue(pairsPriceMap.get(key)));
//                    continue;
//                }
//                BigDecimal totalPrice = new BigDecimal("0");
//                for (ExchageMarketPrice exchageMarketPrice : exchageMarketPrices) {
//                    totalPrice = totalPrice.add(exchageMarketPrice.getPrice());
//                }
//                // in PairsPrice
//                inPairsPriceMapReferenceExchage(key, AVERAGE, totalPrice.divide(new BigDecimal(exchageMarketPrices.size()), DECIMAL, BigDecimal.ROUND_DOWN));
//                redisTemplate.opsForValue().set(key, JsonUtil.writeValue(pairsPriceMap.get(key)));
//            }
//        } catch (Exception e) {
//            LogUtils.error(ReferenceExchagePriceJob.class, "calculationAverage method error ... "+ ExceptionUtils.getStackTrace(e));
//        }
//    }
//
//    /**
//     * 添加对标交易所价格到PairsPriceMap中
//     *
//     * @param redisKey
//     * @param exchangeName
//     * @param price
//     */
//    public void inPairsPriceMapReferenceExchage(String redisKey, String exchangeName, BigDecimal price) {
//        ExchageMarketPrice exchageMarketPrice = ExchageMarketPrice.builder()
//                .exchange(exchangeName)
//                .price(price)
////                .floatingRate(floatingRate)
////                .minPrice(PercentageUtils.calculation(price, floatingRate.multiply(new BigDecimal("-1"))))
////                .maxPrice(PercentageUtils.calculation(price, floatingRate))
//                .inTime(CalendarUtil.getUTCDate().getTime())
//                .build();
//        // 保存到exchagePriceMap中
//        exchagePriceMap.put(redisKey + DELIMITER + exchangeName, exchageMarketPrice);
//        // 保存到PairsPriceMap中
//        if (!pairsPriceMap.containsKey(redisKey)) {
//            pairsPriceMap.put(redisKey, Lists.newArrayList());
//        }
//        pairsPriceMap.get(redisKey).add(exchageMarketPrice);
//
//    }
//
//    /**
//     * 获取交易所最新价格
//     *
//     * @param pairsName
//     * @param unit
//     * @param exchange
//     * @return
//     * @throws Exception
//     */
//    public BigDecimal getPriceByPairsAndExchange(String pairsName, String unit, String exchange) throws Exception {
//        BigDecimal nowPrice = null;
//        String pairsKey = ReferenceExchageConstant.redisExchangeFileName + ":" + pairsName + unit;
//        // 获取内存中的数据
//        if (!CollectionUtils.isEmpty(exchagePriceMap) && exchagePriceMap.containsKey(pairsKey + DELIMITER + exchange)) {
//            nowPrice = exchagePriceMap.get(pairsKey + DELIMITER + exchange).getPrice();
//        } else {
//            // 获取redis该广告交易对的参考交易所数据
//            List<ExchageMarketPrice> exchageMarketPrices = JsonUtil.readValue(redisTemplate.opsForValue().get(pairsKey), new TypeReference<List<ExchageMarketPrice>>() {
//            });
//            for (ExchageMarketPrice exchageMarketPrice : exchageMarketPrices) {
//                if (exchange.equals(exchageMarketPrice.getExchange())) {
//                    nowPrice = exchageMarketPrice.getPrice();
//                    break;
//                }
//            }
//        }
//        // 参考交易所数据没有则去redis获取idax价格转换
//        if (null == nowPrice) {
//            List<Map<String, String>> listMVC = JsonUtil.readValue(clearCacheService.robotCache.get(CommonConstant.MARKET_VALUATION_CNY), new TypeReference<List<Map<String, String>>>() {
//            });
//            for (Map<String, String> map : listMVC) {
//                if (map.get("CoinName").toUpperCase().equals(pairsName)) {
//                    // 获取redis中的CNY和USD价格，但是redis中没有KRW和EUR所以需要通过USD转换
//                    nowPrice = new BigDecimal(
//                            Optional.ofNullable(map.get(toUpperCaseFirstOne(unit.toLowerCase())))
//                                    .orElseGet(() -> ExchangeRateJob.rateTransformation(new BigDecimal(map.get("Usd")), unit.toUpperCase()).toString())
//                    );
//                    break;
//                }
//            }
//        }
//        return nowPrice;
//    }
//
//
//    //首字母转大写
//    public static String toUpperCaseFirstOne(String s) {
//        if (Character.isUpperCase(s.charAt(0))) {
//            return s;
//        } else {
//            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
//        }
//    }
//
//
//}
